/*
 * Created by SharpDevelop.
 * User: EdwardW
 * Date: 30/06/2007
 * Time: 11:42
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using NUnit.Framework;
using System;
using System.IO;
using Wax;
using WatiN.Core;

namespace WaxLibTest
{
    /// <summary>
    /// Tests all of the behaviour of the <see cref="FindMethod"/ > class.
    /// </summary>
    [TestFixture]
    public class FindMethodTest
    {
        /// <summary>
        /// Tests the constructor initializes member fields correctly
        /// </summary>
        [Test]
        public void Constructor()
        {
            FindMethod findMethod = new FindMethod();

            Assert.AreEqual(FindMethodTypes.None, findMethod.MethodType, "Find method type not initialized correctly");
            Assert.IsNotNull(findMethod.Arguments, "Arguments not initialized correctly");
            Assert.AreEqual(0, findMethod.Arguments.Count, "Arguments not initialized correctly");
        }

        /// <summary>
        /// Test the Parse function correctly returns an instance of FindMethod given valid input data
        /// </summary>
        [Test]
        public void Parse()
        {
            FindMethod findMethod = FindMethod.Parse("ById", new string[] { "btnGo" });

            Assert.IsNotNull(findMethod, "FindMethod.Parse returned null");
            Assert.AreEqual(FindMethodTypes.ById, findMethod.MethodType, "FindMethod.Parse did not correctly parse the type");
            Assert.AreEqual(1, findMethod.Arguments.Count, "FindMethod.Parse did not correctly parse the number of arguments");
            Assert.AreEqual("btnGo", findMethod.Arguments[0], "FindMethod.Parse did not correctly parse the argument values");
        }

        /// <summary>
        /// Test that the Parse function correctly handles invalid input data.
        /// </summary>
        [Test, ExpectedExceptionAttribute(typeof(ArgumentNullException))]
        public void ParseInvliadArgs()
        {
            FindMethod findMethod = FindMethod.Parse(null, null);
        }

        /// <summary>
        /// Test that we can correctly parse and return values of <see cref="FindMethodTypes" /> given appropriate input data.
        /// </summary>
        [Test]
        public void ParseFindMethodType()
        {
            Assert.AreEqual(FindMethodTypes.ById, FindMethod.ParseFindMethodType("ById"));
        }

        /// <summary>
        /// Test that parse method correctly handles invalid input data.
        /// </summary>
        [Test, ExpectedExceptionAttribute(typeof(InvalidFindMethodException))]
        public void ParseFindMethodTypeInvalidArgs()
        {
            Assert.AreEqual(FindMethodTypes.ById, FindMethod.ParseFindMethodType("byidx"));
        }

        /// <summary>
        /// Test that you can perform a validation action using the document object
        /// </summary>
        [Test]
        public void FindUsingDocument()
        {
            using (TestManager testManager = new TestManager())
            {
                testManager.Tests.Add(new Test());
                testManager.Tests[0].Commands.Add(CommandTest.CreateCommandGotoUrl(System.IO.Path.Combine(System.Environment.CurrentDirectory, "testpage1.htm")));
                testManager.Tests[0].Commands.Add(ValidateCommandTest.CreateCommandValidate(@"\w*google,Text", "UsingDocument", string.Empty));
                testManager.Execute();                
            }
        }

        [Test]
        /// <summary>
        /// Test that you can retrieve an <see cref="WatiN.Core.Element">element</see> using the
        /// <see cref="FindMethodType.ById">Find.ById</see> method.
        /// </summary>
        public void FindById()
        {
            using (TestManager testManager = new TestManager())
            {
                testManager.Tests.Add(new Test());
                testManager.Tests[0].Commands.Add(CommandTest.CreateCommandGotoUrl(System.IO.Path.Combine(System.Environment.CurrentDirectory, "testpage1.htm")));
                testManager.Execute();

                FindMethod findMethod = FindMethod.Parse("ById", new string[] { "link1" });
                WatiN.Core.Element element = findMethod.Execute(new ExecutionContext(testManager));

                Assert.IsNotNull(element, "FindMethod.Execute using Find.ById returned null.");
            }
        }

        /// <summary>
        /// Finds an <see cref="Element"/> by the value of it's href.
        /// </summary>
        [Test]
        public void FindByUrl()
        {
            using (TestManager testManager = new TestManager())
            {
                testManager.Tests.Add(new Test());
                testManager.Tests[0].Commands.Add(CommandTest.CreateCommandGotoUrl(System.IO.Path.Combine(System.Environment.CurrentDirectory, "testpage1.htm")));
                testManager.Execute();

                FindMethod findMethod = FindMethod.Parse("ByUrl", new string[] { "http://www.google.com" });
                WatiN.Core.Element element = findMethod.Execute(new ExecutionContext(testManager));

                Assert.IsNotNull(element, "FindMethod.Execute using Find.ByUrl returned null.");
            }
        }

        /// <summary>
        /// Test that you can retrieve an <see cref="WatiN.Core.Element">element</see> using the
        /// <see cref="FindMethodTypes.ByName">Find.ByName</see> method.
        /// </summary>
        [Test]
        public void FindByName()
        {
            using (TestManager testManager = new TestManager())
            {
                testManager.Tests.Add(new Test());
                testManager.Tests[0].Commands.Add(CommandTest.CreateCommandGotoUrl(System.IO.Path.Combine(System.Environment.CurrentDirectory, "testpage1.htm")));
                testManager.Execute();

                FindMethod findMethod = FindMethod.Parse("ByName", new string[] { "radio1" });
                WatiN.Core.Element element = findMethod.Execute(new ExecutionContext(testManager));

                Assert.IsNotNull(element, "FindMethod.Execute using Find.ByName returned null.");
            }
        }

        /// <summary>
        /// Test that you can retrieve an <see cref="WatiN.Core.Element">element</see> using the
        /// <see cref="FindMethodTypes.ByAlt">Find.ByAlt</see> method.
        /// </summary>
        [Test]
        public void FindByAlt()
        {
            using (TestManager testManager = new TestManager())
            {
                testManager.Tests.Add(new Test());
                testManager.Tests[0].Commands.Add(CommandTest.CreateCommandGotoUrl(System.IO.Path.Combine(System.Environment.CurrentDirectory, "testpage1.htm")));
                testManager.Execute();

                FindMethod findMethod = FindMethod.Parse("ByAlt", new string[] { "val1" });
                WatiN.Core.Element element = findMethod.Execute(new ExecutionContext(testManager));

                Assert.IsNotNull(element, "FindMethod.Execute using Find.ByAlt returned null.");
            }
        }

        [Test]
        /// <summary>
        /// Test that you can retrieve an <see cref="WatiN.Core.Element">element</see> using the
        /// <see cref="FindMethodType.ByValue">Find.ByValue</see> method.
        /// </summary>
        public void FindByValue()
        {
            using (TestManager testManager = new TestManager())
            {
                testManager.Tests.Add(new Test());
                testManager.Tests[0].Commands.Add(CommandTest.CreateCommandGotoUrl(System.IO.Path.Combine(System.Environment.CurrentDirectory, "testpage1.htm")));
                testManager.Execute();

                FindMethod findMethod = FindMethod.Parse("ByValue", new string[] { "3" });
                WatiN.Core.Element element = findMethod.Execute(new ExecutionContext(testManager));

                Assert.IsNotNull(element, "FindMethod.Execute using Find.ByValue returned null.");
                Assert.AreEqual("3", ((mshtml.IHTMLInputElement)element.HTMLElement).value);
            }
        }

        [Test]
        /// <summary>
        /// Test that you can retrieve an <see cref="WatiN.Core.RadioButton">radio button</see> using the
        /// <see cref="FindMethodTypes.ByName">Find.ByName</see> and Find <see cref="Find.ByValue" /> method.
        /// </summary>
        public void FindByNameAndValue()
        {
            using (TestManager testManager = new TestManager())
            {
                testManager.Tests.Add(new Test());
                testManager.Tests[0].Commands.Add(CommandTest.CreateCommandGotoUrl(System.IO.Path.Combine(System.Environment.CurrentDirectory, "testpage1.htm")));
                testManager.Execute();

                FindMethod findMethod = FindMethod.Parse("ByNameAndValue", new string[] { "radio1", "2" });
                WatiN.Core.Element element = findMethod.Execute(new ExecutionContext(testManager));

                Assert.IsNotNull(element, "FindMethod.Execute using Find.ByName returned null.");
                Assert.IsTrue(element.OuterHtml.Contains("value=2"));
            }
        }

        [Test]
        /// <summary>
        /// Test that you can retrieve an <see cref="WatiN.Core.Element">element</see> using the
        /// <see cref="FindMethodTypes.ByTitle">Find.ByTitle</see> method.
        /// </summary>
        public void FindByTitle()
        {
            using (TestManager testManager = new TestManager())
            {
                testManager.Tests.Add(new Test());
                testManager.Tests[0].Commands.Add(CommandTest.CreateCommandGotoUrl(System.IO.Path.Combine(System.Environment.CurrentDirectory, "testpage1.htm")));
                testManager.Execute();

                FindMethod findMethod = FindMethod.Parse("ByTitle", new string[] { "This is the title attribute for a link." });
                WatiN.Core.Element element = findMethod.Execute(new ExecutionContext(testManager));

                Assert.IsNotNull(element, "FindMethod.Execute using Find.ByTitle returned null.");
                Assert.IsTrue(element.Title.Equals("This is the title attribute for a link."));
            }
        }

        [Test]
        /// <summary>
        /// Test that you attempt to find an element that does not exist an appropriate <see cref="FindMethodException" /> is thrown.
        /// </summary>
        [ExpectedException(typeof(FindMethodException))]
        public void FindInvalidElement()
        {
            using (TestManager testManager = new TestManager())
            {
                testManager.Tests.Add(new Test());
                testManager.Tests[0].Commands.Add(CommandTest.CreateCommandGotoUrl(System.IO.Path.Combine(System.Environment.CurrentDirectory, "testpage1.htm")));
                testManager.Execute();

                FindMethod findMethod = FindMethod.Parse("ByNameAndValue", new string[] { "radio1", "32" });
                WatiN.Core.Element element = findMethod.Execute(new ExecutionContext(testManager));

                Assert.IsNotNull(element, "FindMethod.Execute using Find.ByName returned null.");
                Assert.IsTrue(element.OuterHtml.Contains("value=2"));
            }
        }      
    }
}
